import cgi
import tempfile
import os

# pylint: disable-msg=W0212
class TemporaryFileWrapper(tempfile._TemporaryFileWrapper):
  """Wrapper for TemporaryFiles() that doesn't delete tempfile on close.

  tempfile.NamedTemporaryFile() and TemporaryFile() delete their temp files
  after closing. In the original code sample provided on the Cherrypy wiki
  uses NamedTemporaryFiles() in conjunction with os.link() to move the temp
  file to a destired permanent location. But os.link() isn't supported on
  Windows, so there is no easy way to copy the temp file to a the final location
  before closing the temp file, which deletes it.

  NamedTemporaryFile() on python 2.6 has a delete parameter, which prevents the
  tempfile from being deleted. However, python 2.4 doesn't have this option.
  This workaround is used to provide backwards compatibility to Python 2.4.

  Code for wrapper was taken from Plone: http://svn.plone.org/svn/plone/
    plone.app.blob/trunk/src/plone/app/blob/monkey.py

  From their comments:
  [This is a] variant of tempfile._TemporaryFileWrapper that doesn't rely on the
  automatic windows behaviour of deleting closed files, which even
  happens, when the file has been moved -- e.g. to the blob storage,
  and doesn't complain about such a move either
  """

  unlink = staticmethod(os.unlink)
  isfile = staticmethod(os.path.isfile)

  def close(self):
    if not self.close_called:
      self.close_called = True
      self.file.close()

  def __del__(self):
    self.close()
    if self.isfile(self.name):
      self.unlink(self.name)

class CustomFieldStorage(cgi.FieldStorage):
  """Replacement for cgi.FieldStorage which uses custom tempfile handling.

  Uses the TemporaryFileWrapper() to create a tempfile that isn't deleted after
  closing.

  Below is the original customized FieldStorage from the Cherrypy wiki code
  sample. It doesn't provide windows compatibility, and was thus modified.

  class myFieldStorage(cgi.FieldStorage):
    '''Our version uses a named temporary file instead of the default
    non-named file; keeping it visible (named), allows us to create a
    2nd link after the upload is done, thus avoiding the overhead of
    making a copy to the destination filename.'''

    def make_file(self, binary=None):
        return tempfile.NamedTemporaryFile()
  """

  # pylint: disable-msg=W0613
  def make_file(self, binary=None):
    handle, name = tempfile.mkstemp()
    return TemporaryFileWrapper(os.fdopen(handle, 'w+b'), name)
